import React, {useEffect, useRef, useState} from "react";
import {MinusOutlined, PlusOutlined} from '@ant-design/icons';
import {Button, message, Progress, Select, AutoComplete, Input, Modal} from "antd"
import './index.css'
import axios from "../../../../utils/request";
import ShowResultInfo from "./ShowResultInfo";
import {queryUserGroup} from "../../../../services/group";
import {GroupData} from "../../../../types/group";
const { Option } = Select;

const FaceSearch: React.FC = () => {
    const cameraVideoRef = useRef(null);
    const cameraCanvasRef = useRef(null);
    const [inputValue, setInputValue] = useState<String>("");
    const [percent, setPercent] = useState(0);
    const [showTips, setShowTips] = useState({
        "status": "none",
        "info": "欢迎使用"
    });
    const [stepsInter, setStepsInter] = useState<any>();
    const [lightInter, setLightInter] = useState<any>();
    // 对话框
    const [isModalVisible, setIsModalVisible] = useState(false);
    const [group, setGroup] = useState<String>('one');
    const [groupData, setGroupData] = useState<Array<GroupData>>([]);
    const [options, setOptions] = useState<{ value: string }[]>([]);


    let [rand, setRand] = useState<number>(0);

    let color = ['red', 'yellow', 'blue', 'green', 'pink']

    useEffect(() => {
        queryUserGroup().then(res => {
            console.log(res)
            // @ts-ignore
            setGroupData(res)
        }).catch(err => {
            console.log(err)
        })
    },[])

    const showModal = () => {
        setIsModalVisible(true);
        openMedia()
    };

    function handleOk(){
        setIsModalVisible(false);
        console.log(inputValue)
        // startConvert()
        startSteps()
        setTimeout(() => {
            saveImg()
        },3000)
    }

    const handleCancel = () => {
        setIsModalVisible(false);
    };

    const handleChange = (value: string) => {
        console.log(`selected ${value}`);
        setGroup(value)
    };
    function inputOnChange(e: any) {
        console.log(e.target.value)
        setInputValue(e.target.value)
    }
    const onSearch = (searchText: string) => {
        setOptions(
            !searchText ? [] : [{value:"user1"},{value:"user2"},{value:"user3"},{value:"user4"},],
        );
    };

    const onSelect = (data: string) => {
        console.log('onSelect', data);
        setInputValue(data)
    };

    function autoSearch() {
        message.loading('loading...')
        openMedia()
        // startConvert()
        startSteps()
        setTimeout( () => {
            searchImg()
        },3000)

    }

    function autoSave() {
        showModal()
    }

    function autoClose(){
        stopSteps()
        clearTips()
        closeMedia()
        // stopConvert()
        // @ts-ignore

    }

    function searchSuccess(info:String) {
        setShowTips({
            "status": "success",
            // @ts-ignore
            "info": info
        })
        setPercent(100)
    }

    function searchFail() {
        setShowTips({
            "status": "warning",
            "info": "陌生人"
        })
    }

    function clearTips() {
        setShowTips({
            "status": "none",
            "info": "-"
        })
    }

    function getNextColor(): String {
        return color[rand]
    }


    function startSteps() {
        clearTips()
        clearInterval(stepsInter)
        if (stepsInter == null) {
            const interval = setInterval(() => {
                increase(interval)
            }, 5)
            setStepsInter(interval)
            // searchImg()
        }
    }

    function stopSteps() {
        clearInterval(stepsInter)
        setStepsInter(null)
        setPercent(0)
    }

    function startConvert() {
        clearInterval(lightInter)
        if (lightInter == null) {
            const interval = setInterval(() => {
                rand = (rand + 1) % 5
                setRand(rand)
            }, 1000)
            setLightInter(interval)
        }
    }

    function stopConvert() {
        clearInterval(lightInter)
        setLightInter(null)
    }

    function over() {
        stopSteps()
    }

    const increase = (intr?:any) => {
        setPercent((percent) => {
            if (percent > 100) {
                percent = 100;
                // searchSuccess()
                // stopSteps()
                // stopConvert()
                clearInterval(intr)
                console.log("over")
                return 100;
            }
            let sum:number
            if(percent < 30){
                sum = 0.5
            }else if (percent < 60){
                sum = 0.3
            }else if(percent < 90){
                sum = 0.2
            }else {
                sum = 0.1
            }
            return percent + sum
        });
    };

    const decline = () => {
        let newPercent = percent - 10;
        if (newPercent < 0) {
            newPercent = 0;
        }
        setPercent(newPercent);
    };


    function successFunc(mediaStream: any) {
        const video: any = cameraVideoRef.current;
        // const video = document.getElementById('cameraVideo') as HTMLVideoElement;
        // 旧的浏览器可能没有srcObject
        if ('srcObject' in video) {
            video.srcObject = mediaStream;
        }
        video.onloadedmetadata = () => {
            video.play();
        };
    }

    function errorFunc(err: any) {
        console.log(`${err.name}: ${err.message}`);
        // always check for errors at the end.
    }

    // 启动摄像头
    const openMedia = () => { // 打开摄像头
        // @ts-ignore
        document.getElementById('cameraVideo').style.display = 'block'
        startConvert()
        const opt = {
            audio: false,
            video: {
                width: 300,
                height: 300,
            }
        };
        navigator.mediaDevices.getUserMedia(opt).then(successFunc).catch(errorFunc);


    };
    // 关闭摄像头
    const closeMedia = () => {
        // @ts-ignore
        document.getElementById('cameraVideo').style.display = 'none'
        stopConvert()
        // const video = document.getElementById('cameraVideo') as HTMLVideoElement;
        const video: any = cameraVideoRef.current;
        const stream = video.srcObject;
        if ('getTracks' in stream) {
            const tracks: Array<any> = stream.getTracks();
            tracks.forEach(track => {
                track.stop();
            });
        }
    };

    const getImg = () => { // 获取图片资源
        // const video = document.getElementById('cameraVideo') as HTMLVideoElement;
        // const canvas = document.getElementById('cameraCanvas') as HTMLCanvasElement;
        const video: any = cameraVideoRef.current;
        const canvas: any = cameraCanvasRef.current;
        if (canvas == null) {
            return;
        }
        const ctx = canvas.getContext('2d');
        ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); // 把视频中的一帧在canvas画布里面绘制出来
        const imgStr = canvas.toDataURL(); // 将图片资源转成字符串
        const base64Img = imgStr.split(';base64,').pop(); // 将图片资源转成base64格式
        // closeMedia(); // 获取到图片之后可以自动关闭摄像头
        return {
            base64Img
        };
    };


    const saveImg = () => { // electron项目保存到本地
        let userName = inputValue

        const data: any = getImg();
        console.log(data)

        axios({
            url: "/face/addUser",
            method: "PUT",
            data: {
                'img': data.base64Img,
                'userGroup': group,
                'userName': userName
            }
        }).then(r => {
            console.log(r)
            message.success("保存成功！")
            // stopConvert()
            stopSteps()
            setShowTips({
                status: "save",
                info:"保存成功"
            })
        }).catch(e => {
            message.error(e)
        })
        // 上传图片
    };
    const searchImg = () => { // electron项目保存到本地
        const data: any = getImg();
        console.log(data)
        axios({
            url: "/face/search",
            method: "POST",
            data: {
                'img': data.base64Img,
                'userGroup': group
            }
        }).then(r => {
            console.log(r)
            // message.success("欢迎回来！" + r)
            // @ts-ignore
            searchSuccess(r)
            stopSteps()
            // stopConvert()
        }).catch(e => {
            // message.warning("陌生人！请联系管理员。")
            searchFail()
            console.log(e)
        })
    };

    return <>
        <div className="face-container">
            <div className="circle-steps">
                <Progress
                    width={450}
                    type="circle"
                    strokeColor={{
                        '0%': '#108ee9',
                        '100%': '#87d068',
                    }}
                    percent={percent}
                    format={() => ''}
                />
            </div>
            <div className="div-video" style={{border: '5px solid ' + getNextColor()}} id={"div-video-box"}>
                <video
                    id="cameraVideo"
                    ref={cameraVideoRef}
                    style={{
                        width: '390px', height: '390px', display: 'block', borderRadius: '50%'
                    }}
                >
                </video>
                <div className={"video-content"}><ShowResultInfo param={showTips}/></div>
            </div>
            <canvas
                id="cameraCanvas"
                ref={cameraCanvasRef}
                width={300}
                height={300}
                style={{
                    width: '300px', height: '300px', display: 'none'
                }}
            />
            <div className={"opt-face"}>
                <Button.Group>
                    <Button onClick={decline} icon={<MinusOutlined/>}/>
                    <Button onClick={increase} icon={<PlusOutlined/>}/>
                    <Button onClick={openMedia}>打开摄像头</Button>
                    <Button onClick={closeMedia}>关闭摄像头</Button>
                    <Button onClick={saveImg}>保存信息</Button>
                    <Button onClick={searchImg}>人脸识别</Button>
                </Button.Group>
                <br/>
                <br/>
                <Button.Group>
                    <Button onClick={startConvert}>开始闪灯</Button>
                    <Button onClick={stopConvert}>停止闪灯</Button>
                </Button.Group>
                <br/>
                <br/>
                <Button.Group>
                    <Button onClick={() => searchSuccess('识别成功')}>识别成功</Button>
                    <Button onClick={searchFail}>识别失败</Button>
                    <Button onClick={clearTips}>清除</Button>
                </Button.Group>
                <br/>
                <br/>
                <Button.Group>
                    <Button onClick={startSteps}>开始识别提示</Button>
                    <Button onClick={stopSteps}>停止识别提示</Button>
                </Button.Group>
                <br/>
                <br/>
                <Button.Group>
                    <Button onClick={autoSearch}>一键识别</Button>
                    <Button onClick={autoSave}>一键录入</Button>
                    <Button onClick={autoClose}>一键关闭</Button>
                </Button.Group>
                <br/>
                <br/>
                <Button.Group>
                    <Select defaultValue={group.valueOf()}  style={{ width: 120 }} onChange={handleChange}>
                        {
                            groupData.map((gd,index) => {
                                return <Option key={index} value={gd.groupName}>{gd.groupName}</Option>
                            })
                        }
                    </Select>
                </Button.Group>
            </div>
            <Modal title="添加用户" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
                <AutoComplete
                    options={options}
                    style={{ width: 200 }}
                    onSelect={onSelect}
                    onSearch={onSearch}
                    placeholder="请输入新添加的用户名"
                    children={<Input onChange={inputOnChange} />}
                />
            </Modal>
        </div>
    </>
}

export default FaceSearch;